Module('Phosphor.Events', function () {
    var remove, _slice, slice, EventEmitter;

    this.EventEmitter = EventEmitter = function () { };

    EventEmitter.prototype.getHandlers = function (key) {
        var map = (this.__handlers__ = this.__handlers__ || {});
        return (map[key] = map[key] || []); 
    };

    EventEmitter.prototype.on =
    EventEmitter.prototype.addSubscriber = function (type, callback) {
        this.getHandlers(type).push(callback);
        return this;
    };

    EventEmitter.prototype.removeSubscriber = function (type, callback) {
        if (callback) {
            remove(this.getHandlers(type), callback);
        } else {
            this.__handlers__[type] = [];
        }

        return this;
    };

    EventEmitter.prototype.emit = function (type/*, values*/) {
        var emitter = this,
            args = slice(arguments, 1),
            errs = [];

        this.getHandlers(type).forEach(function (handler) {
            try {
                handler.apply(emitter, args);
            } catch (err) {
                if (type !== 'error') {
                    errs.push(['error', err, handler, args ]);
                } else {
                    throw err;
                }
            }
        });

        errs.forEach(function (args) {
            emitter.emit.apply(emitter, args);
        });

        return this;
    };

    _slice = Array.prototype.slice;

    slice = function (a) {
        return _slice.call.apply(_slice, arguments);
    };

    remove = function (arr, needle) {
        var index = indexOf.call(arr, needle);
        if (index != -1) arr.splice(index, 1);
    };
});
